#include <dao.h>
#include <btBulletDynamicsCommon.h>

#include "btDiscreteDynamicsWorld.h"

static void construct(DaoContext *ctx, DValue *p[], int N) {
    btDispatcher 		*dispatcher = (btDispatcher*) DaoCData_GetData(p[0]->v.cdata);
    btDbvtBroadphase 		*broadphase = (btDbvtBroadphase*) DaoCData_GetData(p[1]->v.cdata);
    btConstraintSolver 		*solver = (btConstraintSolver*) DaoCData_GetData(p[2]->v.cdata);
    btCollisionConfiguration 	*configuration = (btCollisionConfiguration*) DaoCData_GetData(p[3]->v.cdata);

    btDiscreteDynamicsWorld* ptr = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, configuration);

    DaoCData *cdata = DaoContext_PutCData(ctx, ptr, &btDiscreteDynamicsWorldTyper);
};

static void destruct(void *self) {
//    delete (btDiscreteDynamicsWorld*) self;
}

static void setGravity(DaoContext *ctx, DValue *p[], int N) {
    btDiscreteDynamicsWorld*	ptr = (btDiscreteDynamicsWorld*) DaoCData_GetData(p[0]->v.cdata);
    btVector3			*gravity = (btVector3*) DaoCData_GetData(p[1]->v.cdata);

    ptr->setGravity(*gravity);
}

static void addRigidBody(DaoContext *ctx, DValue *p[], int N) {
    btDiscreteDynamicsWorld	*ptr = (btDiscreteDynamicsWorld*) DaoCData_GetData(p[0]->v.cdata);
    btRigidBody			*body = (btRigidBody*) DaoCData_GetData(p[1]->v.cdata);

    ptr->addRigidBody(body);
}

static void stepSimulation(DaoContext *ctx, DValue *p[], int N) {
    btDiscreteDynamicsWorld	*ptr = (btDiscreteDynamicsWorld*) DaoCData_GetData(p[0]->v.cdata);

    ptr->stepSimulation(p[1]->v.f, p[2]->v.i);
}

static DaoFuncItem meth[] = {
    { construct, 	"btDiscreteDynamicsWorld(dispatcher:btDispatcher, broadphase:btDbvtBroadphase, solver:btConstraintSolver, configuration:btCollisionConfiguration)" },

    { setGravity, 	"setGravity(self:btDiscreteDynamicsWorld, gravity:btVector3)" },
    { addRigidBody, 	"addRigidBody(self:btDiscreteDynamicsWorld, body:btRigidBody)" },
    { stepSimulation,	"stepSimulation(self:btDiscreteDynamicsWorld, step:float, maxSubStep:int)" },
    { NULL, NULL }
};

DaoTypeBase btDiscreteDynamicsWorldTyper = {
    "btDiscreteDynamicsWorld",
    NULL,
    NULL,               /* constant */
    meth,       	/* methods */
    { NULL },     	/* parent type */
    { NULL },
    NULL,
    NULL
};
